#include "../include/disk_simulator.h"
#include <fcntl.h>
#include <unistd.h>
#include <cstdlib>
#include <cstring>
#include <sys/stat.h>
#include <sys/types.h>
#include <cstdio>

DiskSimulator::DiskSimulator(const char* file_path, std::size_t size_bytes)
    : fd_(-1), size_(size_bytes), powered_on_(false), file_path_(nullptr) {
    file_path_ = strdup(file_path);
    fd_ = open(file_path, O_RDWR | O_CREAT, 0666);
    if (fd_ >= 0) {
        struct stat st;
        if (fstat(fd_, &st) == 0 && (std::size_t)st.st_size < size_bytes) {
            // 扩展文件到指定大小
            ftruncate(fd_, size_bytes);
        }
        size_ = size_bytes;
    }
    
    // 初始化默认磁盘信息
    strcpy(serial_number_, "DS001234567890");
    strcpy(manufacturer_, "DiskSimulator Inc.");
    strcpy(model_, "DS-1TB-SSD");
    strcpy(firmware_version_, "v1.0.0");
    
    // 初始化SMART信息
    smart_overall_status_ = 1;  // 1=正常, 0=异常
    smart_temperature_ = 35;    // 35度
    smart_power_on_hours_ = 1000;  // 1000小时
    smart_reallocated_sectors_ = 0; // 0个重分配扇区
    
    // 初始化SMART属性
    for (int i = 0; i < 256; i++) {
        smart_attributes_[i].current = 0;
        smart_attributes_[i].worst = 0;
        smart_attributes_[i].threshold = 0;
        smart_attributes_[i].raw_value = 0;
    }
    
    // 设置一些常用的SMART属性默认值
    // 属性1: Raw Read Error Rate
    smart_attributes_[1] = {100, 100, 44, 0};
    // 属性3: Spin Up Time
    smart_attributes_[3] = {95, 95, 0, 0};
    // 属性4: Start/Stop Count
    smart_attributes_[4] = {98, 98, 20, 100};
    // 属性5: Reallocated Sectors Count
    smart_attributes_[5] = {100, 100, 36, 0};
    // 属性7: Seek Error Rate
    smart_attributes_[7] = {100, 100, 30, 0};
    // 属性9: Power-On Hours
    smart_attributes_[9] = {90, 90, 0, smart_power_on_hours_};
    // 属性10: Spin Retry Count
    smart_attributes_[10] = {100, 100, 97, 0};
    // 属性12: Power Cycles
    smart_attributes_[12] = {98, 98, 20, 50};
    // 属性194: Temperature
    smart_attributes_[194] = {65, 65, 0, smart_temperature_};
    // 属性196: Reallocation Event Count
    smart_attributes_[196] = {100, 100, 0, 0};
    // 属性197: Current Pending Sectors
    smart_attributes_[197] = {100, 100, 0, 0};
    // 属性198: Offline Uncorrectable
    smart_attributes_[198] = {100, 100, 0, 0};
}

DiskSimulator::~DiskSimulator() {
    if (fd_ >= 0) close(fd_);
    if (file_path_) free(file_path_);
}

int DiskSimulator::power_on() {
    powered_on_ = true;
    return 0;
}

int DiskSimulator::power_off() {
    powered_on_ = false;
    return 0;
}

bool DiskSimulator::is_powered_on() const {
    return powered_on_;
}

std::size_t DiskSimulator::get_size() const {
    return size_;
}

int DiskSimulator::read(std::size_t offset, void* buf, std::size_t len) {
    if (!powered_on_ || fd_ < 0) return -1;
    if (offset + len > size_) return -2;
    if (lseek(fd_, offset, SEEK_SET) < 0) return -3;
    ssize_t r = ::read(fd_, buf, len);
    return (r == (ssize_t)len) ? 0 : -4;
}

int DiskSimulator::write(std::size_t offset, const void* buf, std::size_t len) {
    if (!powered_on_ || fd_ < 0) return -1;
    if (offset + len > size_) return -2;
    if (lseek(fd_, offset, SEEK_SET) < 0) return -3;
    ssize_t w = ::write(fd_, buf, len);
    return (w == (ssize_t)len) ? 0 : -4;
}

// 新增磁盘信息查询方法实现
int DiskSimulator::get_serial_number(char* sn, std::size_t sn_len) const {
    if (!sn || sn_len == 0) return -1;
    strncpy(sn, serial_number_, sn_len - 1);
    sn[sn_len - 1] = '\0';
    return 0;
}

int DiskSimulator::get_manufacturer(char* manufacturer, std::size_t manufacturer_len) const {
    if (!manufacturer || manufacturer_len == 0) return -1;
    strncpy(manufacturer, manufacturer_, manufacturer_len - 1);
    manufacturer[manufacturer_len - 1] = '\0';
    return 0;
}

int DiskSimulator::get_model(char* model, std::size_t model_len) const {
    if (!model || model_len == 0) return -1;
    strncpy(model, model_, model_len - 1);
    model[model_len - 1] = '\0';
    return 0;
}

int DiskSimulator::get_firmware_version(char* firmware, std::size_t firmware_len) const {
    if (!firmware || firmware_len == 0) return -1;
    strncpy(firmware, firmware_version_, firmware_len - 1);
    firmware[firmware_len - 1] = '\0';
    return 0;
}

int DiskSimulator::set_serial_number(const char* sn) {
    if (!sn) return -1;
    strncpy(serial_number_, sn, sizeof(serial_number_) - 1);
    serial_number_[sizeof(serial_number_) - 1] = '\0';
    return 0;
}

int DiskSimulator::set_manufacturer(const char* manufacturer) {
    if (!manufacturer) return -1;
    strncpy(manufacturer_, manufacturer, sizeof(manufacturer_) - 1);
    manufacturer_[sizeof(manufacturer_) - 1] = '\0';
    return 0;
}

int DiskSimulator::set_model(const char* model) {
    if (!model) return -1;
    strncpy(model_, model, sizeof(model_) - 1);
    model_[sizeof(model_) - 1] = '\0';
    return 0;
}

int DiskSimulator::set_firmware_version(const char* firmware) {
    if (!firmware) return -1;
    strncpy(firmware_version_, firmware, sizeof(firmware_version_) - 1);
    firmware_version_[sizeof(firmware_version_) - 1] = '\0';
    return 0;
}

// 新增SMART信息查询方法实现
int DiskSimulator::get_smart_attribute(int attribute_id, int* current, int* worst, int* threshold, int* raw_value) const {
    if (attribute_id < 0 || attribute_id >= 256 || !current || !worst || !threshold || !raw_value) return -1;
    
    *current = smart_attributes_[attribute_id].current;
    *worst = smart_attributes_[attribute_id].worst;
    *threshold = smart_attributes_[attribute_id].threshold;
    *raw_value = smart_attributes_[attribute_id].raw_value;
    return 0;
}

int DiskSimulator::set_smart_attribute(int attribute_id, int current, int worst, int threshold, int raw_value) {
    if (attribute_id < 0 || attribute_id >= 256) return -1;
    
    smart_attributes_[attribute_id].current = current;
    smart_attributes_[attribute_id].worst = worst;
    smart_attributes_[attribute_id].threshold = threshold;
    smart_attributes_[attribute_id].raw_value = raw_value;
    return 0;
}

int DiskSimulator::get_smart_status(int* overall_status) const {
    if (!overall_status) return -1;
    *overall_status = smart_overall_status_;
    return 0;
}

int DiskSimulator::get_smart_temperature(int* temperature) const {
    if (!temperature) return -1;
    *temperature = smart_temperature_;
    return 0;
}

int DiskSimulator::get_smart_power_on_hours(int* hours) const {
    if (!hours) return -1;
    *hours = smart_power_on_hours_;
    return 0;
}

int DiskSimulator::get_smart_reallocated_sectors(int* count) const {
    if (!count) return -1;
    *count = smart_reallocated_sectors_;
    return 0;
}

// C接口实现
extern "C" {
void* disk_create(const char* file_path, std::size_t size_bytes) {
    return new DiskSimulator(file_path, size_bytes);
}
void disk_destroy(void* disk) {
    delete static_cast<DiskSimulator*>(disk);
}
int disk_power_on(void* disk) {
    return static_cast<DiskSimulator*>(disk)->power_on();
}
int disk_power_off(void* disk) {
    return static_cast<DiskSimulator*>(disk)->power_off();
}
int disk_is_powered_on(void* disk) {
    return static_cast<DiskSimulator*>(disk)->is_powered_on();
}
std::size_t disk_get_size(void* disk) {
    return static_cast<DiskSimulator*>(disk)->get_size();
}
int disk_read(void* disk, std::size_t offset, void* buf, std::size_t len) {
    return static_cast<DiskSimulator*>(disk)->read(offset, buf, len);
}
int disk_write(void* disk, std::size_t offset, const void* buf, std::size_t len) {
    return static_cast<DiskSimulator*>(disk)->write(offset, buf, len);
}

// 新增C接口实现
int disk_get_serial_number(void* disk, char* sn, std::size_t sn_len) {
    return static_cast<DiskSimulator*>(disk)->get_serial_number(sn, sn_len);
}
int disk_get_manufacturer(void* disk, char* manufacturer, std::size_t manufacturer_len) {
    return static_cast<DiskSimulator*>(disk)->get_manufacturer(manufacturer, manufacturer_len);
}
int disk_get_model(void* disk, char* model, std::size_t model_len) {
    return static_cast<DiskSimulator*>(disk)->get_model(model, model_len);
}
int disk_get_firmware_version(void* disk, char* firmware, std::size_t firmware_len) {
    return static_cast<DiskSimulator*>(disk)->get_firmware_version(firmware, firmware_len);
}
int disk_set_serial_number(void* disk, const char* sn) {
    return static_cast<DiskSimulator*>(disk)->set_serial_number(sn);
}
int disk_set_manufacturer(void* disk, const char* manufacturer) {
    return static_cast<DiskSimulator*>(disk)->set_manufacturer(manufacturer);
}
int disk_set_model(void* disk, const char* model) {
    return static_cast<DiskSimulator*>(disk)->set_model(model);
}
int disk_set_firmware_version(void* disk, const char* firmware) {
    return static_cast<DiskSimulator*>(disk)->set_firmware_version(firmware);
}

// 新增SMART C接口实现
int disk_get_smart_attribute(void* disk, int attribute_id, int* current, int* worst, int* threshold, int* raw_value) {
    return static_cast<DiskSimulator*>(disk)->get_smart_attribute(attribute_id, current, worst, threshold, raw_value);
}
int disk_set_smart_attribute(void* disk, int attribute_id, int current, int worst, int threshold, int raw_value) {
    return static_cast<DiskSimulator*>(disk)->set_smart_attribute(attribute_id, current, worst, threshold, raw_value);
}
int disk_get_smart_status(void* disk, int* overall_status) {
    return static_cast<DiskSimulator*>(disk)->get_smart_status(overall_status);
}
int disk_get_smart_temperature(void* disk, int* temperature) {
    return static_cast<DiskSimulator*>(disk)->get_smart_temperature(temperature);
}
int disk_get_smart_power_on_hours(void* disk, int* hours) {
    return static_cast<DiskSimulator*>(disk)->get_smart_power_on_hours(hours);
}
int disk_get_smart_reallocated_sectors(void* disk, int* count) {
    return static_cast<DiskSimulator*>(disk)->get_smart_reallocated_sectors(count);
}
} 